package org.third.integration.vault;

import static org.third.common.utils.CommonUtils.UTC_ZONE;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeaderValueParser;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import org.third.common.utils.CommonUtils;

import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

public class VaultTest {
	public static HttpClient createHttpClient() throws Exception {
		HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
		httpClientBuilder.setConnectionManager(createConnectionManager());
		CloseableHttpClient httpClient = httpClientBuilder.build();

		return httpClient;

//		return HttpClients.createDefault();
//        DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
//        try {
//        	boolean requireValidCertificate=false;
//            if(requireValidCertificate) {
//                return new DefaultHttpClient();
//            } else {
//                SSLSocketFactory factory = new SSLSocketFactory(
//                        trustStrategy == null ? new PermissiveTrustStrategy() : this.trustStrategy,
//                        hostnameVerifier == null ? ALLOW_ALL_HOSTNAME_VERIFIER : this.hostnameVerifier);
//                SchemeRegistry registry = new SchemeRegistry();
//                registry.register(new Scheme("https", 8444, factory));
//                registry.register(new Scheme("http", 8088, PlainSocketFactory.getSocketFactory()));
//                PoolingClientConnectionManager mgr = new PoolingClientConnectionManager(registry);
//                return new DefaultHttpClient(mgr, defaultHttpClient.getParams());
//            }
//        } catch(GeneralSecurityException ex) {
//            logger.error("Error configuring SSL connection.", ex);
//            return null;
//        }finally {
//            if(defaultHttpClient!=null){
//                defaultHttpClient.close();
//            }
//        }
	}

	private static HttpClientConnectionManager createConnectionManager() throws Exception {
		String keyPassword="changeit";
//		SSLContext ctx = SSLContext.getInstance("TLS");
//		KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
		KeyStore keystore = KeyStore.getInstance("PKCS12");
		keystore.load(new FileInputStream("c:/Users/gongyo/ssl/dynasecurw2.hpeswlab.net.p12"),
				keyPassword.toCharArray());
//		keyManagerFactory.init(keyStore, "changeit".toCharArray());
//		ctx.init(keyManagerFactory.getKeyManagers(), new TrustManager[] { new AllowAllTrustManager() }, null);
//		ConnectionSocketFactory ssf = new SSLConnectionSocketFactory(ctx);
//		ssf.setHostnameVerifier(new AllowAllHostnameVerifier());

		SSLContextBuilder builder = new SSLContextBuilder();
		builder.loadTrustMaterial(keystore, new TrustStrategy() {
			@Override
			public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
				return true;
			}
		});
		builder.loadKeyMaterial(keystore, keyPassword.toCharArray());
		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(),
				new String[] { "TLSv1.2" }, null, NoopHostnameVerifier.INSTANCE);
		Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
				.register("http", new PlainConnectionSocketFactory()).register("https", sslsf).build();
		HttpClientConnectionManager ccm = new PoolingHttpClientConnectionManager(registry);
		return ccm;
	}

	static boolean wrapRootValue = false;
	static boolean expectArray = false;

	public void createRestTemplate() throws Exception {
		HttpClient client = createHttpClient();
		HttpComponentsClientHttpRequestFactory commons = new HttpComponentsClientHttpRequestFactory(client);
		RestTemplate template = new RestTemplate(commons);

		// Set up message conversion to handle JSON
		MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
//        JsonMessageConverter jsonConverter = new JsonMessageConverter();
		ObjectMapper jsonMapper = jsonConverter.getObjectMapper();
		jsonMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, this.wrapRootValue);
		jsonMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, (this.wrapRootValue && !expectArray));

		DateFormat iso8601 = new SimpleDateFormat(CommonUtils.DATE_FORMAT_ISO8601);
		iso8601.setTimeZone(UTC_ZONE);
		jsonMapper.setDateFormat(iso8601);

		template.getMessageConverters().clear();
		template.getMessageConverters().add(jsonConverter);
		template.getMessageConverters().add(new StringHttpMessageConverter());
//
//		// Set up request headers
//		ClientHttpRequestInterceptor acceptHeader = new AcceptHeaderHttpRequestInterceptor(MediaType.APPLICATION_JSON);
//		ClientHttpRequestInterceptor contentTypeHeader = new ContentTypeHeaderHttpRequestInterceptor(
//				MediaType.APPLICATION_JSON);
//		BasicAuthHeaderHttpRequestInterceptor basicAuthHeader = new BasicAuthHeaderHttpRequestInterceptor(basicAuthUser,
//				basicAuthPassword);
//		template.setInterceptors(Arrays.asList(acceptHeader, contentTypeHeader, basicAuthHeader));
//
//		String body = "";
//		HttpEntity entity = new HttpBuilder().buildEntityWithBody(body);
//		if (!StringUtils.isEmpty(token)) {
//			entity = new HttpBuilder().setHeader("Authorization", "Bearer " + token).buildEntityWithBody(body);
//		}
//
//		logger.info("request to uri {} header {},and body {}", uri, entity.getHeaders(), entity.getBody());
//
//		ResponseEntity responseEntity = null;
//		if (uriVariables == null) {
//			responseEntity = restTemplate.exchange(uri, method, entity, responseClass);
//		} else {
//			responseEntity = restTemplate.exchange(uri, method, entity, responseClass, uriVariables);
//		}
	}

	static final Logger logger = LoggerFactory.getLogger(VaultTest.class);

	public void vaultPost() {
		// 获取可关闭的 httpCilent
		CloseableHttpClient httpClient = HttpClients.createDefault();
		// 配置超时时间
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(1000).setConnectionRequestTimeout(1000)
				.setSocketTimeout(1000).setRedirectsEnabled(true).build();

		HttpPost httpPost = new HttpPost("http://consentprt.dtac.co.th/webaoc/123SubscriberProcess");
		// 设置超时时间
		httpPost.setConfig(requestConfig);
		// 装配post请求参数
		List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();
		list.add(new BasicNameValuePair("age", "20")); // 请求参数
		list.add(new BasicNameValuePair("name", "zhangsan")); // 请求参数
		try {
			UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8");
			// 设置post求情参数
			httpPost.setEntity(entity);
			HttpResponse response = httpClient.execute(httpPost);
			String strResult = "";
			if (response != null) {
				System.out.println(response.getStatusLine().getStatusCode());
				if (response.getStatusLine().getStatusCode() == 200) {
					strResult = EntityUtils.toString(response.getEntity(), CommonUtils.UTF8);
				} else if (response.getStatusLine().getStatusCode() == 400) {
					strResult = "Error Response: " + response.getStatusLine().toString();
				} else if (response.getStatusLine().getStatusCode() == 500) {
					strResult = "Error Response: " + response.getStatusLine().toString();
				} else {
					strResult = "Error Response: " + response.getStatusLine().toString();
				}
			} else {

			}
			System.out.println(strResult);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (httpClient != null) {
					httpClient.close(); // 释放资源
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		BasicHeaderValueParser parser = new BasicHeaderValueParser();
		String header ="ContentType:application/json";
		
		String serverUrl = "https://dynasecurw2.hpeswlab.net:8200/v1/secret/secret1";
		HttpGet getSecretAction = new HttpGet(serverUrl);
		try {
			HttpClient httpClient = createHttpClient();

			RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000) // 设置连接超时时间
					.setConnectionRequestTimeout(5000) // 设置请求超时时间
					.setSocketTimeout(5000).setRedirectsEnabled(true)// 默认允许自动重定向
					.build();
			getSecretAction.setConfig(requestConfig);
			getSecretAction.setHeader("X-vault-token", "fce792a7-5d46-6968-7a73-4ba759e233ab");
			HttpResponse httpResponse = httpClient.execute(getSecretAction);
			String srtResult = "";
			if (httpResponse.getStatusLine().getStatusCode() == 200) {
				srtResult = EntityUtils.toString(httpResponse.getEntity(), CommonUtils.UTF8);// 获得返回的结果
				System.out.println(srtResult);
			} else if (httpResponse.getStatusLine().getStatusCode() == 400) {
				// ..........
			} else if (httpResponse.getStatusLine().getStatusCode() == 500) {
				// .............
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
